package org.gnf.umls;

import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.rpc.ServiceException;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;

import gov.nih.nlm.umlsks.authorization.*;
import gov.nih.nlm.kss.*;
import gov.nih.nlm.kss.models.meta.attribute.AttributeContext;
import gov.nih.nlm.kss.models.meta.attribute.ConceptAttribute;
import gov.nih.nlm.kss.models.meta.attribute.ConceptAttributeGroup;
import gov.nih.nlm.kss.models.meta.concept.*;
import gov.nih.nlm.kss.models.meta.context.Context;
import gov.nih.nlm.kss.models.meta.context.ContextGroup;
import gov.nih.nlm.kss.models.meta.context.StringCxt;
import gov.nih.nlm.kss.models.meta.meshentry.*;
import gov.nih.nlm.kss.models.meta.relation.RelSource;
import gov.nih.nlm.kss.models.meta.relation.Relation;
import gov.nih.nlm.kss.models.meta.source.*;
import gov.nih.nlm.kss.models.sem.units.*;
import gov.nih.nlm.kss.query.meta.*;
import gov.nih.nlm.kss.query.sem.*;

public class Client {
	private static String username = "";
	private static String password = "";
	private static String umlsRelease = "";

	public Client(String user, String pass){
		username = user;
		password = pass;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if(args==null || args.length != 4){
			System.out.println("Please enter: umlsusername umlspassword inputfilename outputfilename");
			return;
		}
		Client c = new Client(args[0], args[1]);//username password
		String inputFile = args[2];
		String outputFile = args[3];
		Set<String> rterms = Utils.readTermFile(inputFile);
		List<String> terms = new ArrayList<String>(rterms);
		Collections.sort(terms);
		try {
			int p = 0;
			for(String searchString : terms){
				p++;
				System.out.println(p + " "+searchString);
				String triples = c.getTabTriplesForSearchString(searchString);
				if(triples!=null||triples==""){
					FileWriter out = new FileWriter(outputFile, true);
					out.write(triples);
					out.close();
				}else{
					FileWriter out = new FileWriter(outputFile, true);
					out.write(searchString+"\tnone\tnone\n");
					out.close();
				}
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}


	public Model getRDFForConcepts(List<Concept> concepts, Model model) {
		if(model == null){
			model = ModelFactory.createDefaultModel();
		}

		Property umls_semantic_type = model.getProperty("http://gnf.org/UmlsSemanticType");
		umls_semantic_type.addLiteral(RDFS.label, "UMLS Semantic Type");

		Property umls_semantic_group = model.getProperty("http://gnf.org/UmlsSemanticGroup");
		umls_semantic_group.addLiteral(RDFS.label, "UMLS Semantic Group");

		Property source_vocab = model.getProperty("http://gnf.org/UmlsVocab");
		source_vocab.addLiteral(RDFS.label, "UMLS Source Vocab");

		for(Concept c : concepts){
			Resource rdfconcept = model.getResource("http://gnf.org/umls_"+c.getCUI());
			rdfconcept.addLiteral(RDFS.label, c.getCN());

			SemTypeGroup tg = c.getSTYs();
			Object[] contents = tg.getContents();
			for (int i = 0; i < contents.length; i++)
			{
				SemType stype = (SemType)contents[i];
				Resource rdfstype = model.getResource("http://gnf.org/umls_"+stype.getTUI());
				rdfstype.addLiteral(RDFS.label, stype.getSTY());
				rdfconcept.addProperty(umls_semantic_type, rdfstype);

			}
			SemGroupGroup gg = c.getSGs();
			contents = gg.getContents();
			for (int i = 0; i < contents.length; i++)
			{
				SemGroup sgroup = (SemGroup)contents[i];

				Resource rdfsgroup = model.getResource("http://gnf.org/umls_"+sgroup.getAbbrev());
				rdfsgroup.addLiteral(RDFS.label, sgroup.getName());
				rdfconcept.addProperty(umls_semantic_group, rdfsgroup);
			}
			//note that concept attributes aren't being returned by the service..
			/*	ConceptAttributeGroup conceptatts = c.getCAs();
			contents = conceptatts.getContents();
			for (int i = 0; i < contents.length; i++)
			{
				ConceptAttribute cat = (ConceptAttribute)contents[i];
				AttributeContext[] attcons = cat.getAttributes();
				for(AttributeContext attcon : attcons){
					Resource sab = model.getResource("http://gnf.org/source_vocab_"+attcon.getSAB());
					rdfconcept.addProperty(source_vocab, sab);
				}
			} */
			ContextGroup conceptctxs = c.getCXTs();
			contents = conceptctxs.getContents();
			for (int i = 0; i < contents.length; i++)
			{
				Context ctxs = (Context)contents[i];
				StringCxt[] stctx = ctxs.getCXT();
				for(StringCxt ctx : stctx){
					Resource sab = model.getResource("http://gnf.org/source_vocab_"+ctx.getSAB());
					rdfconcept.addProperty(source_vocab, sab);
				}
			}
		}

		return model;
	}


	/**
	 * Given a free text search string, find exact matches to concepts in the UMLS, extract relationships
	 * from the metathesaurus, return as an RDF model.
	 * @param searchString
	 * @return
	 */

	public Model getRDFTriplesForSearchString(String searchString, Resource subject, Model model, boolean relations){

		Property umls_concept = model.getProperty("http://gnf.org/UmlsConcept");

		//map from umls to rdf
		try {
			//limits to GO, MSH (english), NCI, OMIM
			String[] SABS = {"GO","MSH", "NCI", "OMIM"};
			System.out.println("about to get CUIDs");
			List<ConceptId> conceptids = getCUIdsByExactMatch(searchString,SABS,"");

			//if no match
			if(conceptids==null||conceptids.size()==0){
				Resource none = model.getResource("http://gnf.org/no_exact_match");
				subject.addProperty(umls_concept, none);
				return model;
			}

			for(ConceptId conceptid : conceptids){
				System.out.println("about to get concept properties 1");
				List<Concept> concepts = getConceptProperties(conceptid.getCUI(), relations, SABS);
				//get semantic types and semantic groups for the source concepts
				System.out.println("about to get RDF for concepts s: "+model.size());
				getRDFForConcepts(concepts, model);
				System.out.println("added base rdf, size now: "+model.size());

				for(Concept c : concepts){

					Resource rdfconcept = model.getResource("http://gnf.org/umls_"+c.getCUI());
					subject.addProperty(umls_concept, rdfconcept);

					//for relationships
					if(relations){
						Object[] contents  = c.getRels().getContents();
						for (int i = 0; i < contents.length; i++)
						{
							Relation rel = (Relation)contents[i];

							for(RelSource rs :rel.getRelSources()){
								//filtering out non-descriptive relationships like sibling (SIB), synonyms (SY)
								if(rs.getRelA() != null && !rs.getRel().equals("SIB") && !rs.getRel().equals("SY") && !rs.getRel().equals("RQ")){
									Property umlsprop = model.getProperty("http://gnf.org/"+rel.getSAB()+"_"+rs.getRelA());
									umlsprop.addLiteral(RDFS.label, rel.getSAB()+"_"+rs.getRelA());
									Resource object = model.getResource("http://gnf.org/umls_"+rs.getCUI());
									object.addLiteral(RDFS.label, rs.getCN());								

									//subject.addProperty(umlsprop, object);
									rdfconcept.addProperty(umlsprop, object);
									//add some more information about the object of the relationship (but no additional relationships)
									//	System.out.println("about to getRDF for concepts 2 related by "+rs.getRelA());
									getRDFForConcepts(getConceptProperties(rs.getCUI(), false, SABS), model);
								}
							}
						}
					}
				}
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


		return model;
	}


	/**
	 * Given a searchString, tries to find matching concept in UMLS using an exact match query.  
	 * Returns matches and relationships for the concept as a tab-delimited list of triples
	 * @param searchString
	 * @return
	 */
	public String getTabTriplesForSearchString(String searchString){
		String out = "";
		Set<String> triples = new HashSet<String>();

		try {
			List<ConceptId> conceptids = getCUIdsByExactMatch(searchString,null,"");
			for(ConceptId conceptid : conceptids){
				List<Concept> concepts = getConceptProperties(conceptid.getCUI(), true, null);
				for(Concept c : concepts){
					triples.add(searchString+"\tumls:concept\t"+c.getCUI()+"\t"+c.getCN());
					SemTypeGroup tg = c.getSTYs();
					Object[] contents = tg.getContents();
					for (int i = 0; i < contents.length; i++)
					{
						SemType stype = (SemType)contents[i];
						triples.add(c.getCUI()+"\tumls:semantic_type\t"+stype.getTUI()+"\t"+stype.getSTY());
					}
					SemGroupGroup gg = c.getSGs();
					contents = gg.getContents();
					for (int i = 0; i < contents.length; i++)
					{
						SemGroup sgroup = (SemGroup)contents[i];
						triples.add(c.getCUI()+"\tumls:semantic_group\t"+sgroup.getAbbrev()+"\t"+sgroup.getName());
					}
					//for relationships
					contents = c.getRels().getContents();
					for (int i = 0; i < contents.length; i++)
					{
						Relation rel = (Relation)contents[i];

						for(RelSource rs :rel.getRelSources()){
							if(rs.getRelA() != null && !rs.getRel().equals("SIB") && !rs.getRel().equals("SY") && !rs.getRel().equals("RQ")){
								triples.add(c.getCUI()+"\t"+rel.getSAB()+":"+rs.getRelA()+"\t"+rs.getCUI()+"\t"+rs.getCN());
							}
						}
					}
				}
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


		for(String triple : triples){
			out+=triple+"\n";
		}

		return out;
	}

	public static String getTicket() throws MalformedURLException, ServiceException, RemoteException{
		// Locate the authentication web service
		URL authURL = new URL("https://login.nlm.nih.gov:443/auth");
		AuthorizationPortType authPortType =
			new AuthorizationPortTypeServiceLocator().getAuthorizationPort(authURL);

		// Obtain a proxy granting ticket
		String pgt = authPortType.getProxyGrantTicket(username,password);

		// Obtain a proxy granting ticket
		String proxyTicket = 
			authPortType.getProxyTicket(pgt, "http://umlsks.nlm.nih.gov");

		return proxyTicket;
	}

	public static UMLSKSServicePortType getUmlsService(String proxyTicket){
		// Locate the UMLSKS web service
		String ksHost = "http://umlsks.nlm.nih.gov";
		String ksURI = ksHost + "/UMLSKS/services/UMLSKSService";
		URL ksURL;
		UMLSKSServicePortType umlsksService = null;
		try {
			ksURL = new URL(ksURI);
			umlsksService =  new UMLSKSServiceLocator().getUMLSKSServicePort(ksURL);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return umlsksService;
	}

	public static List<ConceptId> getCUIdsBySabCode(String code, String[]sabs) throws MalformedURLException, RemoteException, ServiceException{
		List<ConceptId> CUIDS = new ArrayList<ConceptId>();
		String proxyTicket = getTicket(); 
		// Build the request object
		ConceptIdSabCodeRequest request = new ConceptIdSabCodeRequest();
		request.setCasTicket(proxyTicket);
		request.setRelease(umlsRelease);
		request.setCode(code);
		if(sabs!=null){
			request.setSABs(sabs);
		}
		// Execute the operation
		//System.out.println("executing request");
		UMLSKSServicePortType umlsksService = getUmlsService(proxyTicket);
		ConceptIdGroup group = umlsksService.findCUIBySabCode(request);

		//      System.out.println("Request succeeded");
		// Print the results
		Object[] contents = group.getContents();
		for (int i = 0; i < contents.length; i++)
		{
			ConceptId cid = (ConceptId)contents[i];
			CUIDS.add(cid);
		}
		return CUIDS;
	}	

	/**
	 * http://kswebp1.nlm.nih.gov/DocPortlet/html/dGuide/webservices/metaops/concept/concept1.html
	 * Given a CUID return a complete Concept record
	 * @param CUID
	 * @return
	 * @throws MalformedURLException
	 * @throws RemoteException
	 * @throws ServiceException
	 */
	public static List<Concept> getConceptProperties(String CUID, boolean include_relations, String[] SABs)throws MalformedURLException, RemoteException, ServiceException{
		List<Concept> concepts = new ArrayList<Concept>();
		String proxyTicket = getTicket(); 
		// Build the request object
		ConceptRequest request = new ConceptRequest();
		request.setCasTicket(proxyTicket);
		request.setRelease(umlsRelease);
		request.setCUI(CUID);

		//constrain vocabs to search
		if(SABs != null){
			request.setSABs(SABs);
		}

		//- add switches if streamlining required
		//request.setIncludeTerminology(true);
		request.setIncludeSemanticTypes(true);
		request.setIncludeSemanticGroups(true);

		//this isn't working - no attributes are being returned
		request.setIncludeConceptAttrs(true);
		//TODO use this to speed it up
		//	request.setRelationTypes(relationTypes)
		request.setIncludeContexts(true);
		//  request.setIncludeCooccurrences(true);
		//   request.setIncludeDefinitions(true);
		request.setIncludeRelations(include_relations);
		//   request.setIncludeRelationshipAttrs(true);
		//   request.setIncludeSuppressibles(true);

		// Execute the operation
		//System.out.println("executing request");
		UMLSKSServicePortType umlsksService = getUmlsService(proxyTicket);
		ConceptGroup group = umlsksService.getConceptProperties(request);

		// Print the results
		Object[] contents = group.getContents();
		for (int i = 0; i < contents.length; i++)
		{
			Concept m = (Concept)contents[i];
			concepts.add(m);
		}
		return concepts;
	}

	/**
	 * get mesh strings related to a particular identifier
	 * @param meshid
	 * @return
	 * @throws MalformedURLException
	 * @throws RemoteException
	 * @throws ServiceException
	 */	
	public static List<MeSHInfo> getMeshInfo(String meshid)throws MalformedURLException, RemoteException, ServiceException{
		List<MeSHInfo> mIDS = new ArrayList<MeSHInfo>();
		String proxyTicket = getTicket(); 
		// Build the request object
		MeSHInfoRequest request = new MeSHInfoRequest();
		request.setCasTicket(proxyTicket);
		request.setRelease(umlsRelease);
		request.setDUI(meshid);

		// Execute the operation
		//System.out.println("executing request");
		UMLSKSServicePortType umlsksService = getUmlsService(proxyTicket);
		MeSHInfoGroup group = umlsksService.getMeSHInfo(request);

		// Print the results
		Object[] contents = group.getContents();
		for (int i = 0; i < contents.length; i++)
		{
			MeSHInfo m = (MeSHInfo)contents[i];
			mIDS.add(m);
		}
		return mIDS;
	}

	/**
	 * 
	 * @param searchString
	 * @param CUID
	 * @return
	 * @throws MalformedURLException
	 * @throws RemoteException
	 * @throws ServiceException
	 */	
	public static List<MeSHEntry> getMeshEntries(String searchString, String CUID)throws MalformedURLException, RemoteException, ServiceException{
		List<MeSHEntry> mIDS = new ArrayList<MeSHEntry>();
		String proxyTicket = getTicket(); 
		// Build the request object
		MeSHEntryRequest request = new MeSHEntryRequest();
		request.setCasTicket(proxyTicket);
		request.setRelease(umlsRelease);

		if(searchString!=null){
			request.setTerm(searchString);
		}
		if(CUID!=null){
			request.setCUI(CUID);
		}
		// Execute the operation
		//System.out.println("executing request");
		UMLSKSServicePortType umlsksService = getUmlsService(proxyTicket);
		MeSHEntryGroup group = umlsksService.getMeSHEntries(request);

		// Print the results
		Object[] contents = group.getContents();
		for (int i = 0; i < contents.length; i++)
		{
			MeSHEntry m = (MeSHEntry)contents[i];
			mIDS.add(m);
		}
		return mIDS;
	}


	/**
	 * given a list of source abbreviations like ,MSH, GO, MED, NCBI, get a bunch of descriptive data about the vocabulary
	 * http://kswebp1.nlm.nih.gov/DocPortlet/html/dGuide/javadocs/gov/gov.nih/nlm/kss/models/meta/source/Source.html
	 * @param sabs
	 * @return
	 * @throws MalformedURLException
	 * @throws RemoteException
	 * @throws ServiceException
	 */	
	public static List<Source> describeSources(String[] sabs) throws MalformedURLException, RemoteException, ServiceException{
		String proxyTicket = getTicket(); 
		// to get a CUI by a unique String id
		// Build the request object
		SourceRequest request = new SourceRequest();
		request.setCasTicket(proxyTicket);
		request.setRelease(umlsRelease);

		if(sabs!=null){
			request.setSABs(sabs);
		}

		// Execute the operation
		//System.out.println("executing request");
		UMLSKSServicePortType umlsksService = getUmlsService(proxyTicket);
		SourceGroup group = umlsksService.describeSources(request);
		Object[] contents = group.getContents();
		List<Source> sources = new ArrayList<Source>();
		for (int i = 0; i < contents.length; i++)
		{
			Source s = (Source)contents[i];
			sources.add(s);
		}
		return sources;
	}


	/**
	 * http://kswebp1.nlm.nih.gov/DocPortlet/html/dGuide/webservices/metaops/find/find4.html
	 * produces a lot of results
	 * @param searchString
	 * @param lang
	 * @return
	 * @throws MalformedURLException
	 * @throws RemoteException
	 * @throws ServiceException
	 */
	public static List<ConceptId> getCUIdsByWords(String searchString, String lang) throws MalformedURLException, RemoteException, ServiceException{
		List<ConceptId> CUIDS = new ArrayList<ConceptId>();
		String proxyTicket = getTicket(); 
		// to get a CUI by a unique String id
		// Build the request object
		ConceptIdWordRequest request = new ConceptIdWordRequest();
		request.setCasTicket(proxyTicket);
		request.setRelease(umlsRelease);

		request.setSearchString(searchString);

		if(lang!=null){
			request.setLanguage(lang);
		}

		/* parameters for the service
        http://kswebp1.nlm.nih.gov/DocPortlet/html/dGuide/webservices/metaops/find/find4.html
                setCasTicket (String s)
            - Single-use ticket returned by the AuthorizationPort webservice (REQUIRED)
        setRelease (String s)
            - UMLS release of interest
        setSearchString (String s)
            - input search string
        setSABs (String[] array)
            - set of source abbreviations to search
        setLanguage (String s)
            - language restriction
        setIncludeSuppressibles (boolean b)
            - true if suppressible strings are included in the search
        setCVF (long l)
            - Bit flag for the content view to search

		 */ 
		// Execute the operation
		//System.out.println("executing request");
		UMLSKSServicePortType umlsksService = getUmlsService(proxyTicket);
		ConceptIdGroup group = umlsksService.findCUIByWord(request);

		// Print the results
		Object[] contents = group.getContents();
		for (int i = 0; i < contents.length; i++)
		{
			ConceptId cid = (ConceptId)contents[i];
			CUIDS.add(cid);
		}
		return CUIDS;
	}

	/**
	 * 
	 * @param searchString
	 * @param lang
	 * @return
	 * @throws MalformedURLException
	 * @throws RemoteException
	 * @throws ServiceException
	 */	
	public static List<ConceptId> getCUIdsByNormString(String searchString, String[] sabs, String lang) throws MalformedURLException, RemoteException, ServiceException{
		List<ConceptId> CUIDS = new ArrayList<ConceptId>();
		String proxyTicket = getTicket(); 
		// to get a CUI by a unique String id
		// Build the request object
		ConceptIdNormStringRequest request = new ConceptIdNormStringRequest();
		request.setCasTicket(proxyTicket);

		request.setRelease(umlsRelease);

		request.setSearchString(searchString);
		if(sabs!=null){
			request.setSABs(sabs);
		}
		if(lang!=null){
			request.setLanguage(lang);
		}

		/* parameters for the service
		 *         setCasTicket (String s)
            - Single-use ticket returned by the AuthorizationPort webservice
        setRelease (String s)
            - UMLS release of interest
        setSearchString (String s)
            - input search string
        setSABs (String[] array)
            - set of source abbreviations to search
        setLanguage (String s)
            - language restriction
        setIncludeSuppressibles (boolean b)
            - true if suppressible strings are included in the search
        setCVF (long l)
            - Bit flag for the content view to search
		 */ 
		// Execute the operation
		// System.out.println("executing request");
		UMLSKSServicePortType umlsksService = getUmlsService(proxyTicket);
		ConceptIdGroup group = umlsksService.findCUIByNormString(request);

		// Print the results
		Object[] contents = group.getContents();
		for (int i = 0; i < contents.length; i++)
		{
			ConceptId cid = (ConceptId)contents[i];
			CUIDS.add(cid);
		}
		return CUIDS;
	}	

	/**
	 * Returns a list of concept identifiers with string representations that have exact matches to the query
	 * @param query
	 * @return
	 * @throws MalformedURLException
	 * @throws RemoteException
	 * @throws ServiceException
	 */	
	public static List<ConceptId> getCUIdsByExactMatch(String searchString, String[]sabs, String language) throws MalformedURLException, RemoteException, ServiceException{
		List<ConceptId> CUIDS = new ArrayList<ConceptId>();
		String proxyTicket = getTicket(); 
		// to get a CUI by a unique String id
		// Build the request object
		ConceptIdExactRequest request = new ConceptIdExactRequest();
		request.setCasTicket(proxyTicket);
		request.setRelease(umlsRelease);
		request.setSearchString(searchString);
		if(sabs!=null){
			request.setSABs(sabs);
		}
		if(language!=null){
			request.setLanguage(language);
		}

		// Execute the operation
		//  System.out.println("executing request");
		UMLSKSServicePortType umlsksService = getUmlsService(proxyTicket);
		ConceptIdGroup group = umlsksService.findCUIByExact(request);

		//      System.out.println("Request succeeded");
		// Print the results
		Object[] contents = group.getContents();
		for (int i = 0; i < contents.length; i++)
		{
			ConceptId cid = (ConceptId)contents[i];
			CUIDS.add(cid);
		}
		return CUIDS;
	}




	public static List<SemNetId> getTypesOfGroup(String semGroup) throws MalformedURLException, RemoteException, ServiceException{
		List<SemNetId> SIDS = new ArrayList<SemNetId>();
		String proxyTicket = getTicket(); 

		SemTypesForGroupRequest request = new SemTypesForGroupRequest();
		request.setCasTicket(proxyTicket);
		request.setRelease(umlsRelease);
		request.setSemGroup(semGroup);

		// Execute the operation
		// System.out.println("executing request");
		UMLSKSServicePortType umlsksService = getUmlsService(proxyTicket);
		SemNetIdGroup group = umlsksService.listSemTypesForGroup(request);

		//      System.out.println("Request succeeded");
		// Print the results
		Object[] contents = group.getContents();
		for (int i = 0; i < contents.length; i++)
		{
			SemNetId sid = (SemNetId)contents[i];
			SIDS.add(sid);
		}
		return SIDS;
	}
	/*
	public static List<Concept> getConceptProperties(String CUID)throws MalformedURLException, RemoteException, ServiceException{
		List<Concept> concepts = new ArrayList<Concept>();
		String proxyTicket = getTicket(); 
        // Build the request object
        ConceptRequest request = new ConceptRequest();
        request.setCasTicket(proxyTicket);
        request.setRelease(umlsRelease);
        request.setCUI(CUID);

        //- add switches if streamlining required
 //      request.setIncludeTerminology(true);
       request.setIncludeSemanticTypes(true);
       request.setIncludeSemanticGroups(true);
 //      request.setIncludeConceptAttrs(true);
 //      request.setIncludeContexts(true);
 //      request.setIncludeCooccurrences(true);
       request.setIncludeDefinitions(true);
 //      request.setIncludeRelations(true);
 //      request.setIncludeRelationshipAttrs(true);
 //      request.setIncludeSuppressibles(true);

        // Execute the operation
        System.out.println("executing request");
        UMLSKSServicePortType umlsksService = getUmlsService();
        ConceptGroup group = umlsksService.getConceptProperties(request);

        // Print the results
        Object[] contents = group.getContents();
        for (int i = 0; i < contents.length; i++)
        {
            Concept m = (Concept)contents[i];
            concepts.add(m);
        }
		return concepts;
	}
	 */
	/**
	 * http://kswebp1.nlm.nih.gov/DocPortlet/html/dGuide/webservices/metaops/find/find7.html
	 * 
	 * @param searchString
	 * @return
	 * @throws MalformedURLException
	 * @throws RemoteException
	 * @throws ServiceException

		public static List<ConceptId> getCUIdsByMMTx(String searchString) throws MalformedURLException, RemoteException, ServiceException{
			System.out.println("Approximate matching not working in this release!!");
			return null;
		List<ConceptId> CUIDS = new ArrayList<ConceptId>();
			String proxyTicket = getTicket(); 
	        // to get a CUI by a unique String id
	        // Build the request object
			ConceptIdApproximateMatchRequest request = new ConceptIdApproximateMatchRequest();
	        request.setCasTicket(proxyTicket);

	        request.setRelease(umlsRelease);

	        request.setSearchString(searchString);

	        // Execute the operation
	        System.out.println("executing request");
	        UMLSKSServicePortType umlsksService = getUmlsService();
	        ConceptIdGroup group = umlsksService.findCUIByApproximateMatch(request);

	        // Print the results
	        Object[] contents = group.getContents();
	        for (int i = 0; i < contents.length; i++)
	        {
	            ConceptId cid = (ConceptId)contents[i];
	            CUIDS.add(cid);
	        }
			return CUIDS; 
		}	
	 */

}
